package sg4c.protocol;

import java.awt.event.MouseEvent;
import java.io.IOException;
import sg4c.frontend.RedirectingMouseListener;

public class MouseEventProtocol extends RedirectingMouseListener {

    private final DataOutputProtocol out;
    public static final int CMD_EVENT_MOUSE = 0xee10;
    public static final int CMD_EVENT_MOUSE_MOVED = 0xee11;
    public static final int CMD_EVENT_MOUSE_PRESSED = 0xee12;
    public static final int CMD_EVENT_MOUSE_ENTERED = 0xee13;
    public static final int CMD_EVENT_MOUSE_EXITED = 0xee14;
    public static final int CMD_EVENT_MOUSE_RELEASED = 0xee15;
    public static final int CMD_EVENT_MOUSE_CLICKED = 0xee16;
    public static final int CMD_EVENT_MOUSE_DRAGGED = 0xee17;

    public MouseEventProtocol(DataOutputProtocol proto) {
        this.out = proto;
    }

    @Override
    public void mousePressed(MouseEvent evt) {
        try {
            out.writeInt(CMD_EVENT_MOUSE);
            out.writeInt(CMD_EVENT_MOUSE_PRESSED);
            //out.writeString(".event.mouse.pressed");
            out.writeInt(evt.getX());
            out.writeInt(evt.getY());
            handleButton(evt);
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void mouseReleased(MouseEvent evt) {  // called after a button is released
        try {
            out.writeInt(CMD_EVENT_MOUSE);
            out.writeInt(CMD_EVENT_MOUSE_RELEASED);
            //out.writeString(".event.mouse.released");
            out.writeInt(evt.getX());
            out.writeInt(evt.getY());
            handleButton(evt);
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void mouseClicked(MouseEvent evt) {  // called after a button is released
        try {

            out.writeInt(CMD_EVENT_MOUSE);
            out.writeInt(CMD_EVENT_MOUSE_CLICKED);
            //out.writeString(".event.mouse.clicked");
            out.writeInt(evt.getX());
            out.writeInt(evt.getY());
            handleButton(evt);
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void mouseDragged(MouseEvent evt) {  // called during motion with buttons down
        try {
            out.writeInt(CMD_EVENT_MOUSE);
            out.writeInt(CMD_EVENT_MOUSE_DRAGGED);
            //out.writeString(".event.mouse.dragged");
            out.writeInt(evt.getX());
            out.writeInt(evt.getY());
            handleButton(evt);
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void mouseMoved(MouseEvent evt) {
        try {
            out.writeInt(CMD_EVENT_MOUSE);
            out.writeInt(CMD_EVENT_MOUSE_MOVED);
            //out.writeString(".event.mouse.moved");
            out.writeInt(evt.getX());
            out.writeInt(evt.getY());
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void mouseEntered(MouseEvent evt) {
        try {
            out.writeInt(CMD_EVENT_MOUSE);
            out.writeInt(CMD_EVENT_MOUSE_ENTERED);
            //out.writeString(".event.mouse.entered");
            out.writeInt(evt.getX());
            out.writeInt(evt.getY());
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void mouseExited(MouseEvent evt) {
        try {
            out.writeInt(CMD_EVENT_MOUSE);
            out.writeInt(CMD_EVENT_MOUSE_EXITED);
            //out.writeString(".event.mouse.exited");
            out.writeInt(evt.getX());
            out.writeInt(evt.getY());
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
    }

    private void handleButton(MouseEvent evt) throws IOException {
        int button = 0;
        switch (evt.getButton()) {
            case MouseEvent.BUTTON1:
                button = 1;
                break;
            case MouseEvent.BUTTON2:
                button = 2;
                break;
            case MouseEvent.BUTTON3:
                button = 3;
                break;
        }
        out.writeInt(button);
    }
}
